const Controller = require("egg").Controller;

class UsersController extends Controller {
  async index() {
    const { ctx } = this;
    // Fetch all users from the service
    const users = await ctx.service.users.index();
    // Respond with the list of users
    ctx.body = users;
  }

  async create() {
    const { ctx } = this;
    const user = ctx.request.body;
    // Validate the user data
    try {
      // 参数校验
      ctx.validate(
        {
          username: { type: "string", required: true, allowEmpty: false },
          password: { type: "string", required: true, allowEmpty: false },
          email: {
            type: "string",
            required: true,
            allowEmpty: false,
            format: /\S+@\S+\.\S+/,
          },
        },
        user
      );
    } catch (err) {
      ctx.status = 422;
      ctx.body = {
        code: ctx.status,
        message: "参数校验失败",
        errors: err.errors.map((e) => ({
          field: e.field,
          message: e.message,
        })),
      };
      return;
    }

    try {
      // Create the user
      const newUser = await ctx.service.users.create(user);

      // Respond with the created user
      ctx.status = 201;
      ctx.body = { code: ctx.status, success: true, data: newUser };
    } catch (err) {
      // 特定异常处理
      if (err.name === "UnauthorizedError") {
        ctx.status = 401;
        ctx.body = {
          code: ctx.status,
          error: "AUTH_FAILED",
          message: err.message,
        };
        return;
      }

      // 其他异常抛出给全局处理器
      throw err;
    }
  }

  // 退出登录接口
  async logout() {
    const { ctx, app } = this;
    const token = ctx.request.header.authorization.replace("Bearer ", "");

    // 获取 JWT 过期时间
    const decoded = app.jwt.decode(token);
    const expireTime = decoded.exp - Math.floor(Date.now() / 1000);

    // 将 token 存入 Redis 黑名单，设置过期时间与 JWT 相同
    await app.redis.set(`jwt:blacklist:${token}`, "1", "EX", expireTime);

    ctx.body = { code: 0, message: "退出登录成功" };
  }

  async login() {
    const { ctx, app } = this;
    const user = ctx.request.body;

    try {
      // Validate the user data
      ctx.validate(
        {
          username: { type: "string", required: true, allowEmpty: false },
          password: { type: "string", required: true, allowEmpty: false },
        },
        user
      );
    } catch (err) {
      ctx.status = 422;
      ctx.body = {
        code: ctx.status,
        message: "参数校验失败",
        errors: err.errors.map((e) => ({
          field: e.field,
          message: e.message,
        })),
      };
      return;
    }

    try {
      // Authenticate the user
      const token = app.jwt.sign(
        { id: user.id, exp: Math.floor(Date.now() / 1000) + 24 * 60 * 60 },
        app.config.jwt.secret
      );
      const authenticatedUser = await ctx.service.users.login(user);
      ctx.status = 201;
      ctx.body = {
        code: 0,
        success: true,
        data: {
          userInfo: authenticatedUser,
          token: token, // 返回token
        },
      };
    } catch (err) {
      // 特定异常处理
      if (err.name === "UnauthorizedError") {
        ctx.status = 401;
        ctx.body = {
          code: ctx.status,
          error: "AUTH_FAILED",
          message: err.message,
        };
        return;
      }

      // 其他异常抛出给全局处理器
      throw err;
    }
  }
}

module.exports = UsersController;
